package com.agan.net.knowledge;

import java.nio.ByteBuffer;

public class ByteBufferTest {

    public void testPosLim() throws Exception {
        //第1步：申请一块10个字节的缓冲区
        ByteBuffer buffer = ByteBuffer.allocate(10);
        //第2步：往缓冲区中put()4个字节 "agan"
        buffer.put((byte)'a').put((byte)'g').put((byte)'a').put((byte)'n');
        //第3步：调用flip()方法，作用：切换为读就绪状态
        buffer.flip();
        //第4步：读取最后2个字节
        System.out.println("" + (char) buffer.get() + (char) buffer.get());//打印ag
        //第5步：ByteBuffer.mark()方法，可以对当前position位置进行标记，以后使用ByteBuffer.reset()方法可以使缓冲区的位置重置为以前标记的位置,从而可以返回到标记的位置对缓冲区的数据进行操作。
        buffer.mark();
        //第6步：再次读2个字节
        System.out.println("" + (char) buffer.get() + (char) buffer.get());//打印an
        //第7步：reset到mark的位置
        buffer.reset();
        //第8步：再次读2个字节
        System.out.println("" + (char) buffer.get() + (char) buffer.get());//打印an
        //第9步：调用compact()方法，释放已读数据的空间，准备重新填充缓存区
        buffer.compact();
        System.out.println(buffer.toString());
    }




//    public void testPosLim() throws Exception {
//        //申请一块10个字节的缓冲区
//        ByteBuffer bf = ByteBuffer.allocate(10);
//        System.out.println(bf.toString());
//        //往缓冲区中put()4个字节 "agan"
//        bf.put((byte)'a').put((byte)'g').put((byte)'a').put((byte)'n');
//        System.out.println(bf.toString());
//
//        //调用flip()方法，作用：切换为读就绪状态
//        bf.flip();
//        System.out.println(bf.toString());
//        //读取最后2个字节
//        System.out.println("" + (char) bf.get() + (char) bf.get());
//        System.out.println(bf.toString());
//        //ByteBuffer.mark()方法，可以对当前位置进行标记，以后使用ByteBuffer.reset()方法可以使缓冲区的位置重置为以前标记的位置,从而可以返回到标记的位置对缓冲区的数据进行操作。
//        bf.mark();
//        System.out.println(bf.toString());
//        System.out.println("" + (char) bf.get() + (char) bf.get());
//        System.out.println(bf.toString());
//        bf.reset();
//        System.out.println(bf.toString());
//        System.out.println("" + (char) bf.get() + (char) bf.get());
//        //调用compact()方法，释放已读数据的空间，准备重新填充缓存区
//        bf.compact();
//        System.out.println(bf.toString());
//    }

    /**
     * 缓存区拷贝是一个浅拷贝，就是2个缓存区会共享数据元素，但是每个缓存区的capacity(容量)、position(读写位置)、limit(读写限制)等属性是各自独立的；
     */
    public  void duplicateMemory() {
        ByteBuffer bf = ByteBuffer.allocate(10);
        bf.put("agan".getBytes());
        ByteBuffer tempbf =bf.duplicate();
        tempbf.put("123".getBytes());
        bf.flip();

        //打印结果 agan123
        System.out.println(new String(bf.array()));
        //打印结果 agan123
        System.out.println(new String(tempbf.array()));
    }

    public  void testclean() {
        ByteBuffer bf = ByteBuffer.allocate(10);
        bf.put("agan".getBytes());
        System.out.println(bf);
        System.out.println(new String(bf.array()));
        bf.clear();
        bf.put("123".getBytes());
        System.out.println(bf);
        System.out.println(new String(bf.array()));
    }

   public static void main(String[] args) throws Exception {
        ByteBufferTest buffer=new ByteBufferTest();
//        buffer.testPosLim();
       buffer.duplicateMemory();
       buffer.testclean();

    }


//    public static void main(String args[]){
//        //分配缓冲区（Allocating a Buffer）
//        ByteBuffer buffer = ByteBuffer.allocate(33);
//
//        System.out.println("-------------Test reset-------------");
//        //clear()方法，position将被设回0，limit被设置成 capacity的值
//        buffer.clear();
//        // 设置这个缓冲区的位置
//        buffer.position(5);
//        //将此缓冲区的标记设置在其位置。没有buffer.mark();这句话会报错
//        buffer.mark();
//        buffer.position(10);
//        System.out.println("before reset:      " + buffer);
//        //将此缓冲区的位置重置为先前标记的位置。（buffer.position(5)）
//        buffer.reset();
//        System.out.println("after  reset:       " + buffer);
//
//        System.out.println("-------------Test rewind-------------");
//        buffer.clear();
//        buffer.position(10);
//        //返回此缓冲区的限制。
//        buffer.limit(15);
//        System.out.println("before rewind:       " + buffer);
//        //把position设为0，mark设为-1，不改变limit的值
//        buffer.rewind();
//        System.out.println("before rewind:       " + buffer);
//
//        System.out.println("-------------Test compact-------------");
//        buffer.clear();
//        buffer.put("abcd".getBytes());
//        System.out.println("before compact:       " + buffer);
//        System.out.println(new String(buffer.array()));
//        //limit = position;position = 0;mark = -1; 翻转，也就是让flip之后的position到limit这块区域变成之前的0到position这块，
//        //翻转就是将一个处于存数据状态的缓冲区变为一个处于准备取数据的状态
//        buffer.flip();
//        System.out.println("after flip:       " + buffer);
//        //get()方法：相对读，从position位置读取一个byte，并将position+1，为下次读写作准备
//        System.out.println((char) buffer.get());
//        System.out.println((char) buffer.get());
//        System.out.println((char) buffer.get());
//        System.out.println("after three gets:       " + buffer);
//        System.out.println("\t" + new String(buffer.array()));
//        //把从position到limit中的内容移到0到limit-position的区域内，position和limit的取值也分别变成limit-position、capacity。
//        // 如果先将positon设置到limit，再compact，那么相当于clear()
//        buffer.compact();
//        System.out.println("after compact:       " + buffer);
//        System.out.println("\t" + new String(buffer.array()));
//
//        System.out.println("-------------Test get-------------");
//        buffer = ByteBuffer.allocate(32);
//        buffer.put((byte) 'a').put((byte) 'b').put((byte) 'c').put((byte) 'd')
//                .put((byte) 'e').put((byte) 'f');
//        System.out.println("before flip():       " + buffer);
//        // 转换为读取模式
//        buffer.flip();
//        System.out.println("before get():       " + buffer);
//        System.out.println((char) buffer.get());
//        System.out.println("after get():       " + buffer);
//        // get(index)不影响position的值
//        System.out.println((char) buffer.get(2));
//        System.out.println("after get(index):       " + buffer);
//        byte[] dst = new byte[10];
//        buffer.get(dst, 0, 2);
//        System.out.println("after get(dst, 0, 2):       " + buffer);
//        System.out.println("\t dst:" + new String(dst));
//        System.out.println("buffer now is:       " + buffer);
//        System.out.println("\t" + new String(buffer.array()));
//
//        System.out.println("-------------Test put-------------");
//        ByteBuffer bb = ByteBuffer.allocate(32);
//        System.out.println("before put(byte):       " + bb);
//        System.out.println("after put(byte):       " + bb.put((byte) 'z'));
//        System.out.println("\t" + bb.put(2, (byte) 'c'));
//        // put(2,(byte) 'c')不改变position的位置
//        System.out.println("after put(2,(byte) 'c'):       " + bb);
//        System.out.println("\t" + new String(bb.array()));
//        // 这里的buffer是 abcdef[pos=3 lim=6 cap=32]
//        bb.put(buffer);
//        System.out.println("after put(buffer):       " + bb);
//        System.out.println("\t" + new String(bb.array()));
//    }
}
